package com.jyserver.common.utils;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

	
/**
* @desc: framework of jywork 
* @author: chenym
* @createTime: 2017年12月13日 下午8:16:57
* @version: v1.0
*/
	
public class QRCode {
	    private static int QRCOLOR = 0x000000;   //默认是黑色
	    private static int BackgroundColor  = 0xFFFFFFFF;   //背景颜色
	    private static int fontsize=30; //字体大小
	    private static int Width=400;
	    private static int Height=400;
	
	
	 /**
    * @author: chenym
    * @createTime: 2017年12月13日 下午11:22:20
    * @desc: 创建二维码
    * @param savefile存在文件路径
    * @param content二维码内容
    * @return:Boolean
    */
    public static Boolean MakeQRCode(String savefile,String content)
    {
        try
        {  
        	QRCode zp = new QRCode();
            BufferedImage bim = zp.getQRCodeBufferedImage(content, BarcodeFormat.QR_CODE, zp.getQRCodeHintType());
            ImageIO.write(bim, "png", new File(savefile)); 
            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }

    
    /**
    * @author: chenym
    * @createTime: 2017年12月13日 下午11:31:02
    * @desc: 创建二维码（自定义大小）
    * @param savefile储存文件路径
    * @param content二维码内容
    * @param width二维码宽度
    * @param height二维码高度
    *@return Boolean 
    */
    public static Boolean MakeQRCode(String savefile,String content,int width,int height)
    {
        try
        {  
        	QRCode zp = new QRCode();
            zp.setWidth(width);
            zp.setHeight(height);
            BufferedImage bim = zp.getQRCodeBufferedImage(content, BarcodeFormat.QR_CODE, zp.getQRCodeHintType());
            ImageIO.write(bim, "png", new File(savefile)); 
            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }
    
    /**
    * @author: chenym
    * @createTime: 2017年12月14日 上午12:04:04
    * @desc: 创建带logo二维码
    * @param savefile储存文件路径
    * @param logoPath logo路径
    * @param content二维码内容
    * @param title标题
    *@return Boolean 
    */
    public static Boolean MakeLogoQRCode(String savefile,String logoPath,String content,String title)
    {
        try
        {  
        	QRCode zp = new QRCode();
            BufferedImage bim = zp.getQRCodeBufferedImage(content, BarcodeFormat.QR_CODE, zp.getQRCodeHintType());
            bim=zp.addLogoToQRCode(bim, logoPath, title);
            ImageIO.write(bim, "png", new File(savefile)); 
            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }
    
    /**
    * @author: chenym
    * @createTime: 2017年12月14日 上午12:04:04
    * @desc: 创建带logo二维码（自定义大小）
    * @param savefile储存文件路径
    * @param logoPath logo路径
    * @param content二维码内容
    * @param width二维码宽度
    * @param height二维码高度
    * @param title标题
    *@return Boolean 
    */
    public static Boolean MakeLogoQRCode(String savefile,String logoPath,String content,int width,int height,String title)
    {
        try
        {  
        	QRCode zp = new QRCode();
            zp.setWidth(width);
            zp.setHeight(height);
            BufferedImage bim = zp.getQRCodeBufferedImage(content, BarcodeFormat.QR_CODE, zp.getQRCodeHintType());
            bim=zp.addLogoToQRCode(bim, logoPath, title);
            ImageIO.write(bim, "png", new File(savefile)); 
            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return false;
    }
    
	    
	/**
	* @author: chenym
	* @createTime: 2017年12月13日 下午8:47:18
	* @desc: 解析二维码
	* @param filePath 解析问图片途径
	* @return:String 返回二维码内容
	*/
	public static String  AnalyticQRCode(String filePath) {
		String route = null;
		BufferedImage image;
		try {
			image = ImageIO.read(new File(filePath));
			LuminanceSource source = new BufferedImageLuminanceSource(image);
			Binarizer binarizer = new HybridBinarizer(source);
			BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
			Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
			hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
			Result result = new MultiFormatReader().decode(binaryBitmap, hints);// 对图像进行解码
			route=result.getText();
			return route;
		} catch (IOException e) {
			e.printStackTrace();
		} catch (NotFoundException e) {
			e.printStackTrace();
		}
		return route;
	}
    public BufferedImage addLogoToQRCode(BufferedImage bim, String logoPath, String productName)
    {
        try
        {
            /**
             * 读取二维码图片，并构建绘图对象
             */
            BufferedImage image = bim;
            Graphics2D g = image.createGraphics();
		if(logoPath != null && !logoPath.equals("")){
			 /**
		     * 读取Logo图片
		     */
		    BufferedImage logo = ImageIO.read(new File(logoPath));
		    /**
		     * 设置logo的大小,本人设置为二维码图片的20%,因为过大会盖掉二维码
		     */
		    int widthLogo = logo.getWidth(null)>image.getWidth()*3/10?(image.getWidth()*3/10):logo.getWidth(null), 
		        heightLogo = logo.getHeight(null)>image.getHeight()*3/10?(image.getHeight()*3/10):logo.getWidth(null);
		
		    /**
		     * logo放在中心
		     */
		     int x = (image.getWidth() - widthLogo) / 2;
		     int y = (image.getHeight() - heightLogo) / 2;
		     /**
		     * logo放在右下角
		     *  int x = (image.getWidth() - widthLogo);
		     *  int y = (image.getHeight() - heightLogo);
		     */
		    //开始绘制图片
		    g.drawImage(logo, x, y, widthLogo, heightLogo, null);
		    g.dispose();
		    logo.flush();
		}
           

            //把商品名称添加上去，商品名称不要太长哦，这里最多支持两行。太长就会自动截取啦
            if (productName != null && !productName.equals("")) {
                //新的图片，把带logo的二维码下面加上文字
                BufferedImage outImage = new BufferedImage(Width, Height+45, BufferedImage.TYPE_4BYTE_ABGR);
                Graphics2D outg = outImage.createGraphics();
                //画二维码到新的面板
                outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
                //画文字到新的面板
                outg.setColor(Color.BLACK); 
                outg.setFont(new Font("宋体",Font.BOLD,fontsize)); //字体、字型、字号 
                int strWidth = outg.getFontMetrics().stringWidth(productName);
                if (strWidth >= Width) {
                    String productName1 = productName.substring(0, productName.length()/2);
                    String productName2 = productName.substring(productName.length()/2, productName.length());
                    int strWidth1 = outg.getFontMetrics().stringWidth(productName1);
                    int strWidth2 = outg.getFontMetrics().stringWidth(productName2);
                    outg.drawString(productName1, 200  - strWidth1/2, image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 12 );
                    BufferedImage outImage2 = new BufferedImage(Width, Height+85, BufferedImage.TYPE_4BYTE_ABGR);
                    Graphics2D outg2 = outImage2.createGraphics();
                    outg2.drawImage(outImage, 0, 0, outImage.getWidth(), outImage.getHeight(), null);
                    outg2.setColor(Color.BLACK); 
                    outg2.setFont(new Font("宋体",Font.BOLD,30)); //字体、字型、字号 
                    outg2.drawString(productName2, 200  - strWidth2/2, outImage.getHeight() + (outImage2.getHeight() - outImage.getHeight())/2 + 5 );
                    outg2.dispose(); 
                    outImage2.flush();
                    outImage = outImage2;
                }else {
                    outg.drawString(productName, 200  - strWidth/2 , image.getHeight() + (outImage.getHeight() - image.getHeight())/2 + 12 ); //画文字 
                }
                outg.dispose(); 
                outImage.flush();
                image = outImage;
            }
            image.flush();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            baos.flush();
            ImageIO.write(image, "png", baos);
            baos.close();
            return image;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return null;
    }
    

    
    private static BufferedImage getQRCodeBufferedImage(String content, BarcodeFormat barcodeFormat,Map<EncodeHintType, ?> hints)
    {
        MultiFormatWriter multiFormatWriter = null;
        BitMatrix bm = null;
        BufferedImage image = null;
        try
        {
            multiFormatWriter = new MultiFormatWriter();
            // 参数顺序分别为：编码内容，编码类型，生成图片宽度，生成图片高度，设置参数
            bm = multiFormatWriter.encode(content, barcodeFormat, Width, Height, hints);
            int w = bm.getWidth();
            int h = bm.getHeight();
            image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
            for (int x = 0; x < w; x++)
            {
                for (int y = 0; y < h; y++)
                {
                    image.setRGB(x, y, bm.get(x, y) ? QRCOLOR : BackgroundColor);
                }
            }
        }
        catch (WriterException e)
        {
            e.printStackTrace();
        }
        return image;
    }

    /**
    * @author: chenym
    * @createTime: 2017年12月13日 下午10:15:27
    * @desc: 设置二维码的格式参数
    * @return:Map<EncodeHintType,Object>
    */
    public Map<EncodeHintType, Object> getQRCodeHintType()
    {
        Map<EncodeHintType, Object> hints = new HashMap<EncodeHintType, Object>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hints.put(EncodeHintType.MARGIN, 0);
        hints.put(EncodeHintType.MAX_SIZE, 350);
        hints.put(EncodeHintType.MIN_SIZE, 100);
        return hints;
    }

	
	/**
	* @param qRCOLOR the qRCOLOR to set
	*/
	
    private static void setQRCOLOR(int qRCOLOR) {
	
		QRCOLOR = qRCOLOR;
	}

	
	/**
	* @param backgroundColor the backgroundColor to set
	*/
	
    private static void setBackgroundColor(int backgroundColor) {
	
		BackgroundColor = backgroundColor;
	}

	
	/**
	* @param fontsize the fontsize to set
	*/
	
	private static void setFontsize(int fontsize) {
	
		QRCode.fontsize = fontsize;
	}

	
	/**
	* @param width the width to set
	*/
	
	private static void setWidth(int width) {
	
		Width = width;
	}

	
	/**
	* @param height the height to set
	*/
	
	private static void setHeight(int height) {
	
		Height = height;
	}
    

}

	